// #include "MephistoCAM.h"
#include "BONN_SHUTTER.h"
#include "REG_BITS.h"
// #include "fxxk_extern.h"

// extern int global_abort_exposure;

void bonn_shutter_open( uint32_t *gpio_reg, uint32_t *gpio_in_reg ){

#ifdef _SHUTTER_IS_THORLABS_
	clrbit(*gpio_reg, BIT_SHUTTER);
#else
	setbit(*gpio_reg, BIT_SHUTTER);
#endif

#if defined(_REPORT_SHUTTER_STATUS_)
	bonn_shutter_report_status( gpio_in_reg );
#endif
}

void bonn_shutter_close( uint32_t *gpio_reg, uint32_t *gpio_in_reg ){
	
#ifdef _SHUTTER_IS_THORLABS_
    setbit(*gpio_reg, BIT_SHUTTER);
#else
	clrbit(*gpio_reg, BIT_SHUTTER);
#endif

#if defined(_REPORT_SHUTTER_STATUS_)
	bonn_shutter_report_status( gpio_in_reg );
#endif
}

/*
	测试中发现,快门打开或关闭后,立即开始获取快门状态得到的信息不准确,
	需要延迟一小段时间(usleep(100000);)后才能获取到准确信息,
	如果快门处于打开的状态,SHUTTER_BLADE_A/B的值都是1
*/
void bonn_shutter_report_status( uint32_t *gpio_in_reg ){

    printf("# getting shutter status ...\n");
	usleep(250000*8);

	uint32_t SHUTTER_BLADE_A	= getbit(*gpio_in_reg, BIT_SHUTTER_BLADE_A);
	uint32_t SHUTTER_BLADE_B	= getbit(*gpio_in_reg, BIT_SHUTTER_BLADE_B);
	uint32_t SHUTTER_ERROR 		= getbit(*gpio_in_reg, BIT_SHUTTER_ERROR);

    printf("# --> SHUTTER_BLADE_A   = %2d\n", SHUTTER_BLADE_A);
    printf("# --> SHUTTER_BLADE_B   = %2d\n", SHUTTER_BLADE_B);
    printf("# --> SHUTTER_ERROR     = %2d\n", SHUTTER_ERROR);

	time_t t = time(NULL);
	printf("# status report of Bonn-Shutter\n");
	printf("# UTC:       %s", asctime(gmtime(&t)));

	if( SHUTTER_ERROR == 1 )
		printf("# SHUTTER_ERROR = %u (shutter is OK)\n", SHUTTER_ERROR);
	else
		printf("# SHUTTER_ERROR = %u (shutter is in error)\n", SHUTTER_ERROR);

	if( SHUTTER_BLADE_A == 1 && SHUTTER_BLADE_B == 1 ){
		printf("# shutter is in open state.\n");
	} else {
		printf("# shutter is in closed state.\n");
	}

	printf("\n");
}

void bonn_shutter_exposure( uint32_t *gpio_reg, 
							uint32_t *gpio_in_reg,
							float exp_t_sec ){

	uint32_t sleep_time_us = (uint32_t)(exp_t_sec*1e6);
	
	printf("[BONN_SHUTTER] --> open for %g seconds.\n", exp_t_sec);

	bonn_shutter_open( gpio_reg, gpio_in_reg );

	usleep(sleep_time_us);

	bonn_shutter_close( gpio_reg, gpio_in_reg );
	
	printf("[BONN_SHUTTER] --> close.\n");
	
#if defined(_REPORT_SHUTTER_STATUS_)	
	printf("--> %g seconds exposure finished\n", exp_t_sec);
	printf("--> shutter is closed ...\n");
#endif
}

// void bonn_shutter_exposure_with_abort( 	uint32_t *gpio_reg, 
// 										uint32_t *gpio_in_reg,
// 										float exp_t_sec  ){

// 	// uint32_t sleep_time_us 	= (uint32_t)(exp_t_sec*1e6);
// 	uint32_t usleep_cnt_max	= (uint32_t)(exp_t_sec*1e3);
// 	uint32_t usleep_cnt		= 0;
// 	fprintf(stdout, "[%s] --> usleep_cnt_max: %u\n", __func__, usleep_cnt_max);
// 	fprintf(stdout, "[%s] --> open for %g seconds.\n", __func__, exp_t_sec);

// 	bonn_shutter_open( gpio_reg, gpio_in_reg );

// 	while(1){
		
// 		usleep(1000);
// 		usleep_cnt++;
		
// 		if( (usleep_cnt >= usleep_cnt_max) || (global_abort_exposure == 1) ){
// 			break;
// 		}
// 	}

// 	if( global_abort_exposure == 1 ){
// 		fprintf(stdout, "[%s] --> shutter is closed due to 'exposure abort' signal!\n",__func__);
// 	}

// 	bonn_shutter_close( gpio_reg, gpio_in_reg );
	
// 	// fprintf(stdout, "[%s] --> close.\n", __func__);
// }

//  判断快门是否处于打开的状态
int bonn_shutter_is_open( uint32_t *gpio_in_reg ){

	int is_open = 0;

	uint32_t SHUTTER_BLADE_A	= getbit(*gpio_in_reg, BIT_SHUTTER_BLADE_A);
	uint32_t SHUTTER_BLADE_B	= getbit(*gpio_in_reg, BIT_SHUTTER_BLADE_B);

	is_open = SHUTTER_BLADE_A == 1 && SHUTTER_BLADE_B == 1;

	return is_open;
}
